﻿namespace Codeplex.InertialScroll
{
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    using System.Windows.Threading;

    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();

            CreateChessBoard(grid1);
            //CreateChessBoard(grid2);

            InstrumentScroll();
        }

        private void InstrumentScroll()
        {
            //grid2.SizeChanged += (s, e) => 
            //{
            //};
        }

        /// 
        /// <summary>
        /// Create chess board so we can see inertial scroll behavior</summary>
        /// 
        private void CreateChessBoard(
            Grid                                    grid
        )
        {
            for (int r = 0; r < 50; ++r)
            {
                grid.RowDefinitions.Add(new RowDefinition()
                {
                    Height = new GridLength(80)
                });
            }
            for (int c = 0; c < 50; ++c)
            {
                grid.ColumnDefinitions.Add(new ColumnDefinition()
                {
                    Width = new GridLength(80)
                });
            }

            for (int r = 0; r < grid.RowDefinitions.Count; ++r)
            {
                for (int c = 0; c < grid.ColumnDefinitions.Count; ++c)
                {
                    Border b = new Border()
                    {
                        Background = new SolidColorBrush(((r + c) % 2) == 0 ? Colors.White: Colors.Black)
                    };

                    b.SetValue(Grid.RowProperty, r);
                    b.SetValue(Grid.ColumnProperty, c);
                    b.Child = new TextBlock()
                    {
                        Foreground = new SolidColorBrush(((r + c) % 2) == 1 ? Colors.White: Colors.Black),
                        Text = String.Format("{0},{1}", r, c),
                        FontSize = 20,
                        HorizontalAlignment = System.Windows.HorizontalAlignment.Center,
                        VerticalAlignment = System.Windows.VerticalAlignment.Center
                    };

                    grid.Children.Add(b);
                }
            }
        }

        DispatcherTimer  m_timer; 
        TraversalState   m_stateX;
        TraversalState   m_stateY;
        TraversalScroll  m_scroll;
        DateTime         m_prev;

        private void travelBottom_Click(object sender, RoutedEventArgs e)
        {
            CreateTimer(
                (double) grid1.GetValue(Canvas.TopProperty), -(grid1.ActualHeight - canvas.ActualHeight),
                (double) grid1.GetValue(Canvas.LeftProperty), -(grid1.ActualWidth - canvas.ActualWidth));
        }

        private void travelCenter_Click(object sender, RoutedEventArgs e)
        {
            CreateTimer(
                (double) grid1.GetValue(Canvas.TopProperty), -(grid1.ActualHeight - canvas.ActualHeight) / 2,
                (double) grid1.GetValue(Canvas.LeftProperty), -(grid1.ActualWidth - canvas.ActualWidth) / 2);
        }

        private void travelTop_Click(object sender, RoutedEventArgs e)
        {
            CreateTimer(
                (double) grid1.GetValue(Canvas.TopProperty), 0,
                (double) grid1.GetValue(Canvas.LeftProperty), 0);
        }

        private void CreateTimer(double startx, double stopx, double starty, double stopy)
        {
            if (m_timer == null)
            {
                m_timer          = new DispatcherTimer();
                m_timer.Interval = TimeSpan.FromMilliseconds(10);
                m_timer.Tick    += new EventHandler(m_timer_Tick);

                m_prev           = DateTime.Now;
                m_stateX         = new TraversalState(startx, stopx);
                m_stateY         = new TraversalState(starty, stopy);
                m_scroll         = new TraversalScroll();

                m_timer.Start();
            }
        }

        void m_timer_Tick(object sender, EventArgs e)
        {
            if (m_stateX.Finished)
            {
                m_timer.Stop();
                m_timer = null;
                
            }

            grid1.SetValue(Canvas.TopProperty, m_stateX.CurrentPosition);
            grid1.SetValue(Canvas.LeftProperty, m_stateY.CurrentPosition);

            if (!m_stateX.Finished)
            {
                double delta = (DateTime.Now - m_prev).TotalMilliseconds;

                m_prev   = DateTime.Now;
                m_stateX = m_scroll.Calculate(delta, m_stateX);
                m_stateY = m_scroll.Calculate(delta, m_stateY);
            }
        }
    }
}
